package com.jason.www.controller;

import com.alibaba.fastjson.JSONObject;
import com.jason.www.dao.MovieRepository;
import com.jason.www.index.Movie;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.IteratorUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

import static java.util.Objects.nonNull;

@Slf4j
@RestController
@RequestMapping("/es/movie")
public class MovieESController {
    @Autowired
    MovieRepository movieRepository;


    @PostMapping("/save")
    public String save(@RequestBody Movie movie){
        movieRepository.save(movie);
        return "success";
    }

    @PostMapping("/delete")
    public String delete(@RequestBody Movie movie){
        movieRepository.delete(movie);
        return "success";
    }

    @GetMapping("/delete/{id}")
    public String delete(@RequestBody Long id){
        movieRepository.deleteById(id);
        return "success";
    }

    @PostMapping("/update")
    public String update(@RequestBody Movie movie){
        movieRepository.save(movie);
        return "success";
    }

    @GetMapping("/queryById/{id}")
    public String queryMovieById(@PathVariable Long id){
        Movie movie = movieRepository.queryMovieById(id);
        return JSONObject.toJSONString(movie);
    }


    @GetMapping("/queryAll")
    public String queryAllMovie(){
        List<Movie> list = IteratorUtils.toList(movieRepository.findAll().iterator());
        return JSONObject.toJSONString(list);
    }


    /**
     * 多条件搜索
     * @param movie
     * @return
     */
    @PostMapping("/queryAll")
    public String queryAllMovie(@RequestBody Movie movie){
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        FieldSortBuilder sort = null;
        if(nonNull(movie.getId())){
            builder.must(new QueryStringQueryBuilder(movie.getId().toString()).field(Movie.ID));
        }
        if(nonNull(movie.getTitle())){
            builder.must(QueryBuilders.matchQuery(Movie.TITLE, movie.getTitle()));
        }
        if(nonNull(movie.getDirector())){
            builder.must(QueryBuilders.matchQuery(Movie.DIRECTOR, movie.getTitle()));
        }
        if(nonNull(movie.getYear())){
            builder.must(QueryBuilders.matchQuery(Movie.YEAR_TIME_STAMP, movie.getYearTimeStamp()));
        }
        if(nonNull(movie.getYearStartTimeStamp()) && nonNull(movie.getYearEndTimeStamp())){
            builder.must(QueryBuilders.rangeQuery(Movie.YEAR_TIME_STAMP).gte(movie.getYearStartTimeStamp()).lte(movie.getYearEndTimeStamp()));
        }

        //排序
        if(nonNull(movie.getSortField())){
            sort = SortBuilders.fieldSort(Movie.YEAR)
                    .order((nonNull(movie.getSortDesc()) || movie.getSortDesc())? SortOrder.DESC : SortOrder.ASC);
        }

        //设置分页
        PageRequest page = PageRequest.of(movie.getPage(), movie.getPageSize());

        //构建查询
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //将搜索条件设置到构建中
        nativeSearchQueryBuilder.withQuery(builder);
        //将分页设置到构建中
        nativeSearchQueryBuilder.withPageable(page);
        //将排序设置到构建中
        if (nonNull(sort)){nativeSearchQueryBuilder.withSort(sort);}
        //生产NativeSearchQuery
        NativeSearchQuery query = nativeSearchQueryBuilder.build();
        log.info("查询条件:" + query.getQuery().toString());
        List<Movie> list = IteratorUtils.toList(movieRepository.search(query).iterator());
        return JSONObject.toJSONString(list);
    }

    @PostMapping("/find4Field")
    public String find4Field(@RequestBody Movie movie){
        Page<Movie> page = movieRepository.findByTitleAndDirectorAndYearTimeStampOrYearTimeStampBetween(
                movie.getTitle(), movie.getDirector(), movie.getYearTimeStamp(), movie.getYearStartTimeStamp(), movie.getYearEndTimeStamp(),
                PageRequest.of(movie.getPage(),movie.getPageSize()));
        return JSONObject.toJSONString(page.getContent());
    }

}
